package Imartini

import (
	"github.com/go-martini/martini"
	"github.com/martini-contrib/gzip"
	"github.com/martini-contrib/render"
	"log"
	// "net/http"
	"server/conf"
	"server/framework/API/I"
	"server/lib/redis"
	"server/lib/session"
	"server/lib/templatefunc"
	"strconv"
)

var M *Imartini = &Imartini{map[string]string{}, martini.Classic()}
var API_URL = make(map[string]map[string]map[string]interface{})

var (
	DEBUG, _     = strconv.ParseBool(conf.GET["config"]["DEBUG"])
	LOGO_SIZE, _ = strconv.Atoi(conf.GET["config"]["LOGO_SIZE"])
	LOGO_PATH    = conf.GET["config"]["LOGO_PATH"]
	STATIC_PATH  = conf.GET["config"]["STATIC_PATH"]
	GZIP, _      = strconv.ParseBool(conf.GET["config"]["GZIP"])
	LOGO, _      = strconv.ParseBool(conf.GET["config"]["LOGO"])
	CATURL, _    = strconv.ParseBool(conf.GET["config"]["CATURL"])
	SESSION, _   = strconv.ParseBool(conf.GET["config"]["SESSION"])
	RENDER, _    = strconv.ParseBool(conf.GET["config"]["RENDER"])
	STATIC, _    = strconv.ParseBool(conf.GET["config"]["STATIC"])
	IREDIS, _    = strconv.ParseBool(conf.GET["config"]["REDIS"])
)

func urlfor(s string) string {
	return M.Iroute[s]
}

type Imartini struct {
	Iroute map[string]string
	*martini.ClassicMartini
}

func (im *Imartini) AddAPI(base string, route [][]interface{}) {
	if API_URL[base] == nil {
		API_URL[base] = make(map[string]map[string]interface{})
	}
	for _, j := range route {
		method := j[1].(string)
		pattern := j[2].(string)

		for x, y := range j[3:] {
			apidata := y.(*I.Atype).DOC
			apidata["iurl"] = "/" + base + pattern
			apidata["url"] = "/" + base + pattern + "/" + apidata["type"].(string)
			apidata["method"] = method

			if API_URL[base][apidata["type"].(string)] == nil {
				API_URL[base][apidata["type"].(string)] = make(map[string]interface{})
			}

			API_URL[base][apidata["type"].(string)][pattern] = y.(*I.Atype).DOC

			handler := []martini.Handler{}
			handler = append(handler, y.(*I.Atype).F)
			im.AddRoute(method, apidata["url"].(string), handler...)
			if CATURL {
				log.Printf("|%-40v|%-10v|%-40v|", j[0].(string), method, base+pattern+"/"+apidata["type"].(string))
			}
			if x == len(j[3:])-1 {
				im.AddRoute(method, "/"+base+pattern, handler...)
				if CATURL {
					log.Printf("|%-40v|%-10v|%-40v|", j[0].(string), method, base+pattern)
				}
			}
		}
	}
}

func (im *Imartini) AddIroute(base string, route [][]interface{}, ty ...string) {
	index := 3
	if len(ty) > 0 {
		switch ty[0] {
		case "api":
			index = 4
			im.AddAPI(base, route)
			return
		default:
		}
	}
	for _, j := range route {
		method := j[1].(string)
		pattern := j[2].(string)
		handler := []martini.Handler{}
		for _, y := range j[index:] {
			handler = append(handler, y.(interface{}))
		}
		if base == "" {
			im.Iroute[j[0].(string)] = pattern
			im.AddRoute(method, pattern, handler...)
		} else {
			im.Iroute[j[0].(string)] = "/" + base + pattern
			im.AddRoute(method, "/"+base+pattern, handler...)
		}
		if CATURL {
			log.Printf("|%-40v|%-10v|%-40v|", j[0].(string), method, base+pattern)
		}
	}
}

func init() {
	maps := make([]martini.Handler, 0)
	if LOGO {
		maps = append(maps, logger())
	}
	if GZIP {
		maps = append(maps, gzip.All())
	}
	// maps = append(maps, martini.Recovery())
	if IREDIS {
		maps = append(maps, redis.NREDIS())
	}
	if SESSION {
		maps = append(maps, session.SESSION())
	}
	if STATIC {
		maps = append(maps, martini.Static(STATIC_PATH))
	}
	// maps = append(maps, set_head)
	if RENDER {
		templatefunc.Temfunc["urlfor"] = urlfor
		var renderOption = render.Renderer(render.Options{
			Debug:   DEBUG,
			Base:    "templates",
			Globals: templatefunc.Temfunc,
		})
		maps = append(maps, renderOption)
	}
	M.Handlers(maps...)

	mlog := &Mlog{}
	M.Map(mlog)

	// log.Println(martini.Root)
}
